#!/usr/bin/env python3

import flask
import user_agents
from flask import jsonify, request
from flask_limiter import Limiter
from flask_limiter.util import get_remote_address

from loguru_logger import logger
from pics_api import Pics

app = flask.Flask(__name__)

# 配置速率限制器
limiter = Limiter(
    app=app,
    key_func=get_remote_address,  # 基于IP地址进行限制
    default_limits=[
        "200 per day",  # 每天200次请求
        "50 per hour",  # 每小时50次请求
    ],
    storage_uri="memory://",
    strategy="fixed-window",
)


# 添加错误处理器
@app.errorhandler(403)
def forbidden(e):
    """403 禁止访问页面"""
    return jsonify({"error": "禁止访问"}), 403


@app.errorhandler(404)
def not_found(e):
    """404 页面"""
    return flask.render_template("404.html.j2"), 404


@app.errorhandler(500)
def server_error(e):
    return jsonify({"error": "服务器内部错误"}), 500


@app.get("/")
@app.get("/imgv")
@limiter.limit("10 per minute")
async def imgv():
    keyword = request.args.get("keyword", None)
    tag = request.args.get("tag", None)
    uid = request.args.get("uid", None)
    request_args = dict(request.args)

    pics = Pics(
        keyword=keyword,
        tag=tag,
        uid=uid,
        r18=request.args.get("r18", default=0, type=int),
        num=request.args.get("num", default=10, type=int),
    )

    def add_extra_url(pic: dict):
        """add tags url, author url"""
        server_tags = []
        for s_tag in pic["tags"]:
            server_tag = {
                "href": flask.url_for("imgv", r18=2, tag=s_tag),
                "caption": s_tag,
            }
            server_tags.append(server_tag)
        pic["server_tags"] = server_tags

        pic["author_url"] = flask.url_for("imgv", uid=pic["uid"])
        return pic

    if len(pics) != 0:
        # 检查 user-agent
        user_agent_str = request.headers.get("user-agent")
        if not user_agent_str:
            logger.warning(f"Access denied - No user agent from {request.remote_addr}")
            flask.abort(403)  # 禁止访问

        try:
            ua = user_agents.parse(user_agent_str)
            platform = {
                "mobile": ua.is_mobile,
                "tablet": ua.is_tablet,
                "pc": ua.is_pc,
                "touchable": ua.is_touch_capable,
                "bot": ua.is_bot,
            }
        except (AttributeError, TypeError):
            # 处理无效的 user-agent
            logger.warning(
                f"Access denied - Invalid user agent from {request.remote_addr}"
            )
            flask.abort(403)  # 禁止访问

        logger.info(f"Access from ⚓ [{ua}], Remote addr: {request.remote_addr}")

        response_title = None
        if keyword or tag:
            if keyword:
                title_arg = keyword
            else:
                title_arg = tag
            response_title = f'🔎 Result of "{title_arg}"'
        elif uid:
            author = pics.raw_datas[0]["author"]
            response_title = f'🔎 Pics of author: "{author}"'

        return flask.render_template(
            "imgv.html.j2",
            pics=list(map(add_extra_url, pics.to_list())),
            args=request_args,
            count=len(pics),
            platform=platform,
            title=response_title,
        )
    else:
        logger.info(f"Pictures related to {request_args} are not found")
        flask.abort(404)


if __name__ == "__main__":
    app.run(
        host="0.0.0.0",
        port=5000,
    )
